package edu.cmu.cs.webapp.ioms.models.util;

import edu.cmu.cs.webapp.ioms.dao.DataAccessException;
import edu.cmu.cs.webapp.ioms.dao.FinReportDAO;
import edu.cmu.cs.webapp.ioms.dao.impl.FinReportDAOImpl;

public class FinancialReport {

	//private FinReportDAO finDAO = new FinReportTestDAOImpl();
	private FinReportDAO finDAO = new FinReportDAOImpl();
	
	private FinancialRecord[] finRecords;

	// private OrderDAO orderDAO;

	public FinancialReport() {

	}

	public FinancialReport(FinancialRecord[] finRecords) {
		// orderDAO = new OrderDAO();
		this.finRecords = finRecords;
	}

	public FinancialRecord[] getAll() {
		return finRecords;
	}

	public void setByMonth(int fromYear, int fromMonth, int toYear, int toMonth) {
		double[] revenue=null;
		try {
			revenue = finDAO.getRevenueByMonth(fromYear, fromMonth,
					toYear, toMonth);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		double[] cost=null;
		try {
			cost = finDAO.getCostByMonth(fromYear, fromMonth, toYear,
					toMonth);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int numMonth = ((toYear - fromYear) * 12 + toMonth) - fromMonth + 1;
		finRecords = new FinancialRecord[numMonth];
		for (int i = 0; i < numMonth; i++) {
			int year = getDate(fromYear, fromMonth, i)[0];
			int month = getDate(fromYear, fromMonth, i)[1];
			FinancialRecord each = new MonthRecord(year, month);
			each.setCost(cost[i]);
			each.setRevenue(revenue[i]);
			finRecords[i] = each;
		}
	}

	public void setByYear(int fromYear, int fromMonth, int toYear, int toMonth) {

		int numYears = toYear - fromYear + 1;
		FinancialRecord[] yearRecords = new YearRecord[numYears];
		FinancialRecord temp = null;

		fromMonth = 1;
		toMonth = 12;
		int numMonth = ((toYear - fromYear) * 12 + toMonth) - fromMonth + 1;
		for (int i = 0; i < numYears; i++) {
			yearRecords[i] = new YearRecord(fromYear + i);
		}
		setByMonth(fromYear, fromMonth, toYear, toMonth);
		for (int i = 0; i < numMonth; i++) {
			temp = finRecords[i];
			int tempToYear = temp.getYear();
			int yearIndex = getYearIndex(fromYear, tempToYear);

			yearRecords[yearIndex].setRevenue(yearRecords[yearIndex]
					.getRevenue()
					+ temp.getRevenue());
			yearRecords[yearIndex].setCost(yearRecords[yearIndex].getCost()
					+ temp.getCost());

		}
		finRecords = yearRecords;

	}

	public void setByQuarter(int fromYear, int fromMonth, int toYear,
			int toMonth) {

		int fromQua = getQuarter(fromMonth);
		int toQua = getQuarter(toMonth);
		fromMonth = getFromMonthbyQuarter(fromQua);
		toMonth = getToMonthbyQuarter(toQua);
		setByMonth(fromYear, fromMonth, toYear, toMonth);
		int numMonth = ((toYear - fromYear) * 12 + toMonth) - fromMonth + 1;
		int numQuarter = numMonth / 3;
		FinancialRecord temp = null;
		FinancialRecord[] quaRecords = new QuarterRecord[numQuarter];
		for (int i = 0; i < numMonth; i++) {
			temp = finRecords[i];
			int tempToYear = temp.getYear();
			int tempToMonth = temp.getMonth();
			int quaIndex = getQuarterIndex(fromYear, fromMonth, tempToYear,
					tempToMonth);
			quaRecords[quaIndex] = new QuarterRecord(tempToYear,
					getQuarter(tempToMonth));
		}

		for (int i = 0; i < numMonth; i++) {
			temp = finRecords[i];
			int tempToYear = temp.getYear();
			int tempToMonth = temp.getMonth();
			int quaIndex = getQuarterIndex(fromYear, fromMonth, tempToYear,
					tempToMonth);

			quaRecords[quaIndex].setRevenue(quaRecords[quaIndex].getRevenue()
					+ temp.getRevenue());
			quaRecords[quaIndex].setCost(quaRecords[quaIndex].getCost()
					+ temp.getCost());

		}
		finRecords = quaRecords;

	}

	private int[] getDate(int year, int month, int offset) {
		int[] result = new int[2];
		int temp = month + offset;

		if (temp % 12 == 0)
			month = 12;
		else {
			month = temp % 12;
			year += temp / 12;
		}
		result[0] = year;
		result[1] = month;
		return result;
	}

	private int getQuarter(int month) {
		int qua = 1;
		if (month >= 1 && month <= 3)
			qua = 1;
		if (month >= 4 && month <= 6)
			qua = 2;
		if (month >= 7 && month <= 9)
			qua = 3;
		if (month >= 10 && month <= 12)
			qua = 4;
		return qua;
	}

	private int getFromMonthbyQuarter(int qua) {
		if (qua == 1)
			return 1;
		if (qua == 2)
			return 4;
		if (qua == 3)
			return 7;
		else
			return 10;
	}

	private int getToMonthbyQuarter(int qua) {
		if (qua == 1)
			return 3;
		if (qua == 2)
			return 6;
		if (qua == 3)
			return 9;
		else
			return 12;
	}

	private int getQuarterIndex(int fromYear, int fromMonth, int toYear,
			int toMonth) {
		int numMonth = ((toYear - fromYear) * 12 + toMonth) - fromMonth + 1;
		return (numMonth - 1) / 3;
	}

	private int getYearIndex(int fromYear, int toYear) {

		return toYear - fromYear;
	}

}
